<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>调整</title>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
  <style>
    
   
    .custom-cursor {
        cursor: url('imgs/down_cursor.png'), auto; /* 指定自定义光标图片路径 */
    }
     table {
    border-collapse: collapse;
  }
  th, td {
    border: 1px solid black;
    min-width: 60px; /* 设置最小宽度 */
    height: 40px; /* 设置高度 */
    position: relative; /* 为"把手"定位 */
  }
  .resize-handle {
    position: absolute;
    width: 10px;
    height: 100%;
    top: 0;
    right: 0;
    cursor: ew-resize;
    background-color: #f2f2f2; /* "把手"的颜色 */
  }
    </style>
    <p>移动光标以查看坐标：</p>
    <div id="cursorCoordinates"></div>
    <p>移动光标以查看坐标2：</p>
    <div id="positionCell"></div>
    <p>移动光标以查看坐标3：</p>
    <div id="positionCell2"></div>
<canvas id="myCanvas" width="1300" height="1200"></canvas>

<script>
  $(document).ready(function() {


    $(document).on("contextmenu", function(e) {
    e.preventDefault(); // 阻止默认的右键菜单弹出
    });

    var canvas = $('#myCanvas')[0];
    var ctx = canvas.getContext('2d');
    var curOnBorder=0; //光标在边框上
    var curOnBorderAndButtonDown=0; //光标在边框上且左键按钮被按下  
    var onBottomLine=0; //光标在表格底部边框上

      // 定义自定义光标样式
    var myCursor = "url('imgs/down_cursor.png'), auto";


    var jsonData = [
    
    {
      "cells": [
        {"content": "A1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "B1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "C1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "D1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "E1", "width": 60, "height": 40, "borderSize": 1, "showBorder": true}
      ]
    },
    {
      "cells": [
        {"content": "A1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "B1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "C1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "D1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "E1", "width": 60, "height":  40, "borderSize": 1, "showBorder": true}
      ]
    },
	{
	  "cells": [
	    {"content": "A1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
	    {"content": "B1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
	    {"content": "C1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
	    {"content": "D1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
	    {"content": "E1", "width": 60, "height":  40, "borderSize": 1, "showBorder": true}
	  ]
	},
    {
      "cells": [
        {"content": "A1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "B1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "C1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "D1", "width": 160, "height": 40, "borderSize": 1, "showBorder": true},
        {"content": "E1", "width": 60, "height": 40, "borderSize": 1, "showBorder": true}
      ]
    }
  // ... 其他行，以此类推

    ];

    var isSelecting = false;
    var selectionStart = {};
    var selectedCells = [];
    var currentSelection = [];

    function drawCell(ctx, cell, startX, startY, isSelected) {
      // 绘制单元格的边框
      if (cell.showBorder) {
        ctx.strokeRect(startX, startY, cell.width, cell.height);
      }
      
      // 绘制选择区域颜色
      if (isSelected) {
        ctx.fillStyle = 'lightblue';
        ctx.fillRect(startX, startY, cell.width, cell.height);
      }

      // 设置文本对齐方式，并绘制文本内容
      ctx.textBaseline = 'middle';
      ctx.textAlign = 'center';
      ctx.fillStyle = 'black';
      ctx.fillText(cell.content, startX + cell.width / 2, startY + cell.height / 2);
    }

    function drawTable(data) {
      var startX = 0;
      var startY = 0;

      data.forEach(function(rowData, rowIndex) {
        rowData.cells.forEach(function(cell, cellIndex) {
          var isCellSelected = selectedCells.some(function(selCell) {
            return selCell.row === rowIndex && selCell.col === cellIndex;
          });
          drawCell(ctx, cell, startX, startY, isCellSelected);
          startX += cell.width; // 移动到下一个单元格的起始位置
        });
        startX = 0; // 重置X位置到行的开始
        startY += rowData.cells[0].height; // 移动到下一行的起始位置
      });
    }



    function getCellFromCoords(x, y) {
      var startX = 0;
      var startY = 0;

      for (var rowIndex = 0; rowIndex < jsonData.length; rowIndex++) {
        var row = jsonData[rowIndex].cells;
        for (var cellIndex = 0; cellIndex < row.length; cellIndex++) {
          var cell = row[cellIndex];
          if (x >= startX && x <= startX + cell.width &&
              y >= startY && y <= startY + cell.height) {
            return {row: rowIndex, col: cellIndex};
          }
          startX += cell.width;
        }
        startX = 0;
        startY += row[0].height;
      }

      return null;
    }

    function updateSelection(x, y) {
      var cell = getCellFromCoords(x, y);
      if (cell && (selectionStart.row != cell.row || selectionStart.col != cell.col)) {
        currentSelection = [];
        for (var i = Math.min(selectionStart.row, cell.row); i <= Math.max(selectionStart.row, cell.row); i++) {
          for (var j = Math.min(selectionStart.col, cell.col); j <= Math.max(selectionStart.col, cell.col); j++) {
            currentSelection.push({row: i, col: j});
          }
        }
        redraw();
      }
    }



    function redraw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      drawTable(jsonData);
      currentSelection.forEach(function(cell) {
        var startX = cell.col * jsonData[0].cells[cell.col].width;
        var startY = cell.row * jsonData[cell.row].cells[0].height;
        var cellData = jsonData[cell.row].cells[cell.col];
        drawCell(ctx, cellData, startX, startY, true);
      });
    }


      drawTable(jsonData);

      var whereCurIs=0;                  //1=上下，2=左右,3=首行顶部
      var currentSelectedCellRowIndex=0; //当前选中的单元格所在行索引
      var currentSelectedCellIndex=0;    //当前选中的单元格所在列索引
      var tableRows=0;                   //当前表格行数
      var curOnTheRightBoarder=0;         //光标在右侧边框上
      var curOnTheBottomBoarder=0;        //光标在底部边框上
      var tableLines=0

    function updateTotalHeight()
    {
           tableTotalHeight=0; //重新计算表格总高
            for(var n=0;n<tableLines;n++)
            {
              tableTotalHeight+=jsonData[n].cells[0].height;
            }
    }

    
      canvas.addEventListener('mousemove', function(e) {

      var canvasOffset = $('#myCanvas').offset();

      var cursorX = event.pageX;
      var cursorY = event.pageY;

   

     
      var currentCell=null;

      var keysArray = Object.keys(jsonData);
      
	    tableLines= keysArray.length;
      
      $('#positionCell2').text('jsonData.length:(' + tableLines +')');

      var startX = canvasOffset.left;
      var startY = canvasOffset.top;
      var found=0;
      var selectCellLeft=0;
      var selectCellTop=0;
      var selectCellRight=0;
      var selectCellBottom=0;

      var offset = 6; // 光标与边线的偏移量
      var curOffsetx=offset;
      var curOffsety=offset;
      var curoffsetmy=offset;
  
      var inRightPosition=0;

      var tableTotalWidth=0;
      var tableTotalHeight=0;
      
        for(var n=0;n<tableLines;n++)
        {
          tableTotalHeight+=jsonData[n].cells[0].height;
        }
        for(var m=0;m<tableRows;m++)
        {
          tableTotalWidth+=jsonData[0].cells[m].width;
        }
      //光标在边框上且左键按钮被按下 正在调整中 ,此时不做单元格OverMoev监听，直到释放调整
    
      if( curOnBorder==1&&curOnBorderAndButtonDown==1)
      {

        //currentSelectedCellRowIndex=0; //当前选中的单元格所在行索引
        //currentSelectedCellIndex=0;    //当前选中的单元格所在列索引

      

        var direct='调整列宽';
        if(whereCurIs==1)
        direct='调整行高';

        console.log('正在调整中 '+direct+' 操作方向:'+whereCurIs+' 列数：'+tableRows+' 光标坐标：(' + cursorX + ', ' + cursorY + ' curOnBorder:'+curOnBorder+', curOnBorderAndButtonDown:'+curOnBorderAndButtonDown+' 当前行：'+currentSelectedCellRowIndex+' 当前列:'+currentSelectedCellIndex+')');


        //处理光标在表格最右边的情况
        if(curOnTheRightBoarder==1)
        {
            var totalOffsetX=0;
            console.log('正在调整中 宽度---------- ');
            for(var j=0;j<currentSelectedCellIndex;j++)
            {
              
              console.log('表格最右边_调整单元格大小，当前更新列:'+currentSelectedCellRowIndex+" 列号："+String(j));
                totalOffsetX+=jsonData[currentSelectedCellRowIndex].cells[j].width;//选中行下前N列的宽
        
            }
            //更新当前列单元格的宽
            for(var i=0;i<tableRows-1;i++)
            {
              var tempwidth=cursorX-canvasOffset.left-totalOffsetX;
              console.log('表格最右边_调整单元格大小，当前更新列:'+currentSelectedCellRowIndex+" 上单元格宽度："+String(tempwidth));
              //console.log('调整单元格大小，当前更新列上单元格高度：'+);
              if(currentSelectedCellIndex>=0) //
              //jsonData[currentSelectedCellIndex].cells[i].width=tempwidth;
              {
                if(tempwidth>=15)
                jsonData[i].cells[currentSelectedCellIndex].width=tempwidth;
              }
              
          
            }
            tableTotalWidth=0;//重新计算表格总宽度
            for(var m=0;m<tableRows;m++)
            {
              tableTotalWidth+=jsonData[0].cells[m].width;
            }
            redraw();
            return ;
        }

        if(curOnTheBottomBoarder==1)//处理光标在表格最下边的情况
        {

          var totalOffsetY=0;
            for(var j=0;j<tableLines-1;j++)
            {
              
              console.log('表格最下边_curOnTheBottomBoarder==1 调整单元格大小，当前更新列:'+j+" 列号：0 单元格高："+String(jsonData[j].cells[0].height));
                totalOffsetY+=jsonData[j].cells[0].height;//最一行之前N行高之和
        
            }

            var currentRowHeight=cursorY-canvasOffset.top-totalOffsetY; //最后一行的高度正在变化，所以要减去前面的行高
            
            //更新当最后一行单元格的高
            for(var i=0;i<tableRows;i++)
            {
             
              console.log('表格最下边_curOnTheBottomBoarder==1 调整单元格大小，当前更新行:'+currentSelectedCellIndex+" 上单元格宽度："+String(currentRowHeight));
              //console.log('调整单元格大小，当前更新列上单元格高度：'+);
              if(tableLines>=0)
              {
                if(curOnTheBottomBoarder==1)
                {
                  if(currentRowHeight>=15)
                  jsonData[tableLines-1].cells[i].height=currentRowHeight; //对最后一行进行更新
                }
               
              }
              
          
            }

            tableTotalHeight=0
            updateTotalHeight(); //重新计算表格总高

            redraw();
            return ;

        }

        if(whereCurIs==1)//调整行高:同一行所有单元格的行高都改变，bottom的Y值等于cursorY
        {
			      //计算当前单元格上面所有单元格的高度。tableLines
            var totalOffsetY=0;
            for(var j=0;j<currentSelectedCellRowIndex;j++)
            {
              if(j<currentSelectedCellRowIndex-1)
              {
                totalOffsetY+=jsonData[j].cells[0].height;
              }
                      
            }
            //更新当前行单元格的高度
            for(var i=0;i<tableRows;i++)
            {
              var tempheight=cursorY-canvasOffset.top-totalOffsetY;
              console.log('调整单元格大小，当前更新列:'+currentSelectedCellRowIndex+" 上单元格高度："+String(tempheight));
              //console.log('调整单元格大小，当前更新列上单元格高度：'+);
			        if(currentSelectedCellRowIndex-1>=0)
              {
                if(tempheight>=15)
                jsonData[currentSelectedCellRowIndex-1].cells[i].height=tempheight;
              }
             
			 
            }
        }
		
		if(whereCurIs==2)//调整列单元格宽:同一行所有单元格的行高都改变，bottom的Y值等于cursorY
		{
			//计算当前单元格上面所有单元格的宽度。tableLines
			var totalOffsetX=0;
			for(var j=0;j<currentSelectedCellIndex-1;j++)
			{
				
        console.log('调整单元格大小，当前更新列:'+currentSelectedCellRowIndex+" 列号："+String(j));
					totalOffsetX+=jsonData[currentSelectedCellRowIndex].cells[j].width;//选中行下前N列的宽
	
			}
		    //更新当前列单元格的宽
		    for(var i=0;i<tableLines;i++)
		    {
		      var tempwidth=cursorX-canvasOffset.left-totalOffsetX;
		      console.log('调整单元格大小，当前更新列:'+currentSelectedCellRowIndex+" 上单元格宽度："+String(tempwidth));
		      //console.log('调整单元格大小，当前更新列上单元格高度：'+);
			  if(currentSelectedCellIndex-1>=0)
        {
          if(tempwidth>=15)
          jsonData[i].cells[currentSelectedCellIndex-1].width=tempwidth;
        }
		      
			 
		    }
		}
		
		//isSelecting = false;
		currentSelection = [];
        redraw();
        return;
      }
      
      
      $('#cursorCoordinates').text('光标坐标：(' + cursorX + ', ' + cursorY +')');
      //表格选中监测
      //遍历行
      for (var rowIndex = 0; rowIndex < tableLines; rowIndex++) {
        //$('#positionCell').text('rowIndex:(' + rowIndex +')');       
        var row = jsonData[rowIndex].cells; //表格行单元格数组
         //遍历行中的每个单元格       
         //遍历列 
         if(row.length>0)
         tableRows=row.length;

        for (var cellIndex = 0; cellIndex < row.length; cellIndex++) { 
          // 获取单元格的位置信息
          console.log();
          var cell = row[cellIndex];//当前行第N个的单元格
          console.log('rowIndex:(' + rowIndex +' cellIndex:'+cellIndex+')  单元格位置：cell.x:(' + startX +' cell.y:'+startY+')'+' 光标坐标：(' + cursorX + ', ' + cursorY + ')');
          if (cursorX >= startX && cursorX <= startX + cell.width &&
              cursorY >= startY && cursorY <= startY + cell.height) {
            //console.log('============rowIndex:(' + rowIndex +' cellIndex:'+cellIndex+')');
            selectCellLeft=startX;
            selectCellTop=startY;
            selectCellRight=startX+cell.width;
            selectCellBottom=startY+cell.height;
            document.body.style.cursor = 'defalut';
            currentCell = cell;
            found=1;
            if(cellIndex==tableLines)//光标在最后一行
            {
              console.log('光标在最后一列 =rowIndex:(' + rowIndex +' cellIndex:'+cellIndex+')');
            }
            if(curOnBorderAndButtonDown==0) //只有在结构上没有按下按钮时，才进行选中
            {
              currentSelectedCellRowIndex=rowIndex;
              currentSelectedCellIndex=cellIndex;
            }
           
            break;
          }
          startX += cell.width;
        }
        if(found==1 )
        break;
        startX = 0;
        startY += row[0].height;
      }
     

        //光标在最右边上
        if((tableTotalWidth-offset+canvasOffset.left)<cursorX&&cursorX<(tableTotalWidth+offset+canvasOffset.left))
         {
          //光标在表格的最右边上
           curOnTheRightBoarder=1;
           whereCurIs=2;
           var myCursor = "url('imgs/l_r_cursor.png') 16 16,auto";
            document.body.style.cursor = myCursor;
            console.log('监测到 光标在表格最右边边边------------------totalWidth:'+tableTotalWidth+' cursorX:'+cursorX+' offset:'+offset);
            return;
        
         }
         else
         {
           curOnTheRightBoarder=0;

         }


         //curOnTheBottomBoarder
         if((tableTotalHeight-offset+canvasOffset.top)<cursorY&&cursorY<(tableTotalHeight+offset+canvasOffset.top))
         {
          //光标在表格的最下边上
           curOnTheBottomBoarder=1;
           whereCurIs=1;
           var myCursor = "url('imgs/u_d_cursor.png') 16 16,auto";
            document.body.style.cursor = myCursor;
            console.log('监测到 光标在表格最下边边边------------------totalWidth:'+tableTotalWidth+' cursorX:'+cursorX+' offset:'+offset);
            return;
         }else
         {
           curOnTheBottomBoarder=0;
         }

        //光标在上方
       if(cursorX>selectCellLeft&&cursorX<selectCellRight&&cursorY>selectCellTop-offset&&cursorY<selectCellTop+offset)
       {
           
            if(currentSelectedCellRowIndex==0)
            {
              //光标在第一行的上边，变光标为单向下箭头
              var myCursor = "url('imgs/down_cursor.png') 8 8,auto";
              document.body.style.cursor = myCursor;
              inRightPosition=1;
              whereCurIs=3;
               //console.log('监测到 光标在单元格首行顶线上-------------------');

            }
            else
            {
              console.log('监测到  光标在单元格的上边线上 当前行：'+currentSelectedCellRowIndex+' 当前列:'+currentSelectedCellIndex);
              var myCursor = "url('imgs/u_d_cursor.png') 16 16,auto";
              document.body.style.cursor = myCursor;//上下双箭头
              //document.body.style.cursor = 'ns-resize';//上下双箭头
              inRightPosition=1;
              whereCurIs=1;

            }
           
       }
 
   

        //光标在左方
       if(cursorX>selectCellLeft-offset&&cursorX<selectCellLeft+offset&&cursorY>selectCellTop&&cursorY<selectCellBottom)      
       {

        console.log('监测到 光标在单元格首行最左边线上：-------------------：：：'+currentSelectedCellIndex);
            if(currentSelectedCellIndex==0)//光标在第一列的左边
            {
               //光标在第一行的上边，变光标为单向下箭头
               var myCursor = "url('imgs/right_cursor.png')8 8, auto";
              document.body.style.cursor = myCursor;
             // console.log('光标在单元格首行最左边线上-------------------');
           
            }
            else
            {
              //document.body.style.cursor = 'ew-resize';//左右双箭头
             // console.log('光标在单元格左边线上-------------------');
             var myCursor = "url('imgs/l_r_cursor.png') 16 16,auto";
              document.body.style.cursor = myCursor;//上下双箭头
            }
           
           
            
            inRightPosition=1;//在正确的位置上
            whereCurIs=2;
       }
       

       if(inRightPosition==0)
        {
          document.body.style.cursor = 'default';
        }
       else
        {
          curOnBorder=1;
        }

      if(curOnBorderAndButtonDown==1)
      {
       
        if(whereCurIs==1)//光标在单元格上方，调节高度
        { 
          console.log('调整单元格大小，当前所在行:'+currentSelectedCellRowIndex+" 表格列数： "+tableRows);
          if(currentSelectedCellRowIndex!=0)//第一行不处理
          {

            //更新当前行单元格的高度
            for(var i=0;i<tableRows;i++)
            {
              console.log('调整单元格大小，当前更新列:'+currentSelectedCellRowIndex+" 上单元格高度："+cursorY-canvasOffset);
              //jsonData[currentSelectedCellRowIndex].cells[i].height=cursorY-selectCellTop-canvasOffset;
            }
            
          }

        }



      }
      
      // //表格选中功能
      // if (isSelecting) {
      //   var rect = canvas.getBoundingClientRect();
      //   var x = e.clientX - rect.left;
      //   var y = e.clientY - rect.top;
      //   updateSelection(x, y);
      // }


      
    });
  /*===================================================================
  OnMouseUp 处理鼠标释放事件
  =====================================================================*/

    canvas.addEventListener('mouseup', function(e) {

      if (e.which === 1) 
      {
          e.preventDefault();
      }

    if(curOnTheRightBoarder==1)//当调节单元格右边框时，释放。
    {
      
      curOnTheRightBoarder=0;  
      curOnTheBottomBoarder=0;
      curOnBorder=0;//释放单元格边线
      curOnBorderAndButtonDown=0;
      console.log('表格最右侧单元格鼠标左键被释放。');
      return;
    }
    if(curOnTheBottomBoarder==1)
    {
      curOnTheBottomBoarder=0;
      curOnTheRightBoarder=0;  
      curOnBorder=0;//释放单元格边线
      curOnBorderAndButtonDown=0;
      console.log('表格最下行鼠标左键被释放。');
      return;  
    }

	 if( curOnBorder==1&&curOnBorderAndButtonDown==1)
	 { curOnBorderAndButtonDown=0;//释放单元格调整按钮
     curOnBorder=0;//释放单元格边线
     document.body.style.cursor ='default';//恢复默认光标
     console.log('表格调整键被释放。');
	   return;//在调整时，不做选择操作。
		 
	 }
   
      // if (isSelecting) {
      //   isSelecting = false;
      //   selectedCells = selectedCells.concat(currentSelection);
      //   currentSelection = [];
       
      //   redraw();
      // }
    });


  /*===================================================================
      OnMouseDown 处理鼠标左键按下事件
  =====================================================================*/
    canvas.addEventListener('mousedown', function(e) {
		

      // if (event.which === 3) {

      //   curOnTheRightBoarder=0;//释放单元格边线
      //   curOnBorder=0;//释放单元格边线
      //   curOnBorderAndButtonDown=0;//释放单元格调整按钮
      // // 处理鼠标右键事件
      // console.log('鼠标右键被按下。');

      
      // // 阻止默认的右键菜单
      // event.preventDefault();

      //     selectedCells = []; // Clear previous selection, if we want to support multiple selections we should not clear this
      //     currentSelection = [selectionStart];
      //     redraw();
      //     return;

      // }

     //光标在表格的最右边上
     if(curOnTheRightBoarder==1)
     {
                var myCursor = "url('imgs/l_r_cursor.png') 16 16,auto";
                document.body.style.cursor = myCursor;
                curOnBorderAndButtonDown=1; //光标在边框上且左键按钮被按下  

                curOnBorder=1;

               

                console.log('表格最右边上鼠标左键被按下。');
                return;
     }

         //光标在表格的最下边上
    if(curOnTheBottomBoarder==1)
     {
                var myCursor = "url('imgs/u_d_cursor.png') 16 16,auto";
                document.body.style.cursor = myCursor;
                curOnTheBottomBoarder=1; 
                curOnBorderAndButtonDown=1; //光标在边框上且左键按钮被按下

                curOnBorder=1;

               

                console.log('表格最下边上鼠标左键被按下。');
                return;
     }
          
            
  
    if( curOnBorder==1)         //光标在边框上
    {
      console.log('光标在边框上-鼠标左键被按下。');
      curOnBorderAndButtonDown=1; //光标在边框上且左键按钮被按下  
      return;
    }
    
    
        // var rect = canvas.getBoundingClientRect();
        // var x = e.clientX - rect.left;
        // var y = e.clientY - rect.top;
      
        // selectionStart = getCellFromCoords(x, y);
        // if (selectionStart) {
        //   isSelecting = true;
        //   selectedCells = []; // Clear previous selection, if we want to support multiple selections we should not clear this
        //   currentSelection = [selectionStart];
        //   redraw();
        // }
  
       
  
      });


   
  });
</script>

</body>
</html>
